package org.kumas.bigdata.hdfs3.fsdirectory;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.util.UUID;

/*************************************************
 * TODO_Kumas
 *  Author： KumasZhang
 *  DateTime： 2021-12-05 10:22
 *  Description： 
 **/
public class FsUtils {
    public static Block[] fileToBlocks(File file) throws IOException {
        return bytesToBlocks(fileToBytes(file));
    }

    public static byte[] fileToBytes(File file) throws IOException {
        if (!file.exists()) {
            throw new FileNotFoundException(file.getName());
        }
        long fileSize = file.length();
        if (fileSize > Integer.MAX_VALUE) {
            System.out.println("file too big...");
            return null;
        }

        ByteBuffer byteBuffer = ByteBuffer.allocate((int) fileSize);
        try (
                FileInputStream fs = new FileInputStream(file);
                FileChannel channel = fs.getChannel();
                ) {
            while ((channel.read(byteBuffer)) > 0) {
                // do nothing
            }
        }
        return byteBuffer.array();
    }

    public static Block[] bytesToBlocks(byte[] bytes) {
        int pages = Math.toIntExact(bytes.length % Block.BLOCK_SIZE == 0 ? bytes.length / Block.BLOCK_SIZE : bytes.length / Block.BLOCK_SIZE + 1);

        Block[] blocks = new Block[pages];
        for (int i = 0; i < pages; i++) {
            Block block = new Block(UUID.randomUUID().toString().substring(0, 6));
            if (pages == 1) {
                blocks[0] = block;
                block.setContent(bytes, bytes.length);
            } else {
                //todo：可以改进算法，使用类似bytebuf的指针来计算大小
                byte[] page = new byte[Block.BLOCK_SIZE];
                int len = 0;
                if (i == pages - 1) {//最后一页
                    len = Math.toIntExact(bytes.length % Block.BLOCK_SIZE == 0 ? Block.BLOCK_SIZE : bytes.length % Block.BLOCK_SIZE);
                    System.arraycopy(bytes, i * Block.BLOCK_SIZE, page, 0, len);

                } else {
                    len = Block.BLOCK_SIZE;
                    System.arraycopy(bytes, i * Block.BLOCK_SIZE, page, 0, len);
                }
                block.setContent(page, len);
                blocks[i] = block;
            }

        }
        return blocks;
    }
}
